package com.pipayshop.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.green20220302.models.ImageModerationRequest;
import com.aliyun.green20220302.models.ImageModerationResponse;
import com.aliyun.green20220302.models.ImageModerationResponseBody;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.teautil.models.RuntimeOptions;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pipayshop.config.CommonConfig;
import com.pipayshop.entity.Image;
import com.pipayshop.entity.OSSProperties;
import com.pipayshop.exception.BusinessException;
import com.pipayshop.mapper.ImageMapper;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import com.aliyun.green20220302.Client;
import com.aliyun.teaopenapi.models.Config;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @author xiaoqiu
 * @date 2024/9/12 16:09
 * @description 文件上传工具类
 */
@Slf4j
@Component
public class FileUploadUtil {
    private static final String SEPARATOR = "/";
    private static final String PRE = "images/";
    private static final String UPLOAD_PRE = "pipayshop-api/src/main/resources/static/";
    //用户头像存储位置
    public static final String AVATAR = "avatar";
    //首页轮播图存储位置
    public static final String BG_IMG = "bg_img";
    //网店商品图存储位置
    public static final String SHOP_COMMODITY_IMG = "shop_commodity_img";
    //网店背景广告图存储位置
    public static final String SHOP_IMG = "shop_img";
    //实体店商品图存储位置
    public static final String STORE_COMMODITY_IMG = "store_commodity_img";
    //实体店背景广告图存储位置
    public static final String STORE_IMG = "store_img";
    //酒店头像图片储存位置
    public static final String ROOM_TOP_IMG = "room_top_img";
    // 网店首页的分类栏的图片
    public static final String SHOP_TOP_CATEGORY_IMG = "shop_category_top";
    //实体店分类图片储存位置
    public static String CATEGORY_IMG = "store_category_img";
    //酒店轮播图储存位置
    public static String ROOM_IMAGE_LIST = "room_image_list";
    //网店头像图片储存位置
    public static String SHOP_TOP_IMAGS = "shop_top_imags";
    //商品图片的地址集合储存位置
    public static String SHOP_IMAGS_LIST = "shop_imags_list";
    //商品详情图片的地址集合
    public static String SHOP_DETAIL_IMAGS = "shop_detail_imags";
    //实体店商品展示图上传
    public static String STORE_COMMODITY_TOP_IMAGE_UP = "store_commodity_top_imageUp";
    //实体店商品轮播图上传
    public static String STORE_COMMODITY_IMAGE_UP = "store_commodity_image_Up";
    //实体店展示图上传
    public static String STORE_TOP_IMAGE_UP = "store_top_imageUp";
    //实体店轮播图上传
    public static String STORE_IMAGE_UP = "store_image_Up";
    //PI ID 图上传
    public static String PI_ID_IMAGE = "pi_id_image";
    //PI ID 图上传
    public static String ECHANGE_IMG = "echange_img";
    //    @Value("${aliyun.oss.bucketName}")
//    private static String bucketName;
//    @Value("${aliyun.oss.endpoint}")
//    private static String  endpoint;
//    @Value("${aliyun.oss.accessKeyId}")
//    private static String  accessKeyId;
//    @Value("${aliyun.oss.accessKeySecret}")
//    private static String accessKeySecret;
    private static String bucketName = "pi-pipayshop";
    private static String endpoint = "oss-rg-china-mainland.aliyuncs.com";
    private static String accessKeyId = "LTAI5t8UQg483WwPP4SGBgXL";
    private static String accessKeySecret = "HYjPo92cItN16nrx8ClyiVDKCXmSx2";


    @Autowired
    private CommonConfig commonConfig;

    @Autowired
    private static FileUploadUtil fileUploadUtil;


    @PostConstruct
    public void init() {
        fileUploadUtil = this;
        fileUploadUtil.commonConfig = commonConfig;
    }

    /**
     * 文件上传
     */
    public String uploadFile(MultipartFile multipartFile, String path) {
        if (multipartFile.isEmpty()) {
            throw new BusinessException("文件不能为空");
        }

        String fileName = multipartFile.getOriginalFilename();

        if ("".equals(fileName)) {
            return "文件名不能为空";
        }

        String postStr = fileName.substring(fileName.lastIndexOf("."));
        String preStr = StringUtil.generateShortId();
        fileName = preStr + postStr;

        String imagePath = fileUploadUtil.commonConfig.getImagePath();
        File readPath = new File(imagePath + File.separator + path);
        if (!readPath.isDirectory()) {
            readPath.mkdirs();
        }
        //将文件复制到指定路径
        String separator = File.separator;
        File destFile = new File(readPath.getAbsolutePath() + separator + fileName);
        try {
            FileCopyUtils.copy(multipartFile.getBytes(), destFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return SEPARATOR + PRE + path + SEPARATOR + fileName;
    }

    /**
     * 删除文件
     */
    public boolean deleteFile(String fileName) {
        File file = new File(UPLOAD_PRE + fileName);
        //判断文件存不存在
        if (!file.exists()) {
            return false;
        } else {
            ;
            //判断这是不是一个文件，ps：有可能是文件夹
            if (file.isFile()) {
                return file.delete();
            }
        }
        return false;
    }

    /**
     * 将一张图片异步裁剪压缩为多张小规格图片
     */
    public static void asyCropping(String path, List<String> sizeList) {
        // 对图片进行批量压缩存储
//        sizeList.stream()
//                .parallel()
//                .peek(size -> {
//                    String[] sizeArray = size.split(",");
//                    int length = Integer.parseInt(sizeArray[0]);
//                    int wide = Integer.parseInt(sizeArray[1]);
//                    try {
//                        File file = new File("pipayshop-api/src/main/resources/static/" + path);
//                        String fileName = file.getName();
//                        String fileExtension = "";
//                        int dotIndex = fileName.lastIndexOf(".");
//                        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
//                            fileExtension = fileName.substring(dotIndex + 1);
//                        }
//                        String newFileName = file.getAbsolutePath()
//                                .replaceFirst("\\.([a-z]+)", "_" + length +"_" + wide + "."+fileExtension);
//                        Thumbnails.of(file)
//                                .size(length, wide)
//                                .outputFormat(fileExtension)
//                                .toFile(newFileName);
//                    } catch (IOException e) {
//                        throw new RuntimeException(e);
//                    }
//                }).count();

        OSS ossClient = new OSSClientBuilder().build(
                endpoint,
                accessKeyId,
                accessKeySecret);


        // 对图片进行批量压缩存储并上传至OSS
        sizeList.stream()
                .parallel()
                .peek(size -> {
                    String[] sizeArray = size.split(",");
                    int length = Integer.parseInt(sizeArray[0]);
                    int wide = Integer.parseInt(sizeArray[1]);
                    try {
                        File file = new File("pipayshop-api/resources/" + path);
                        String fileName = file.getName();
                        String fileExtension = "";
                        int dotIndex = fileName.lastIndexOf(".");
                        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
                            fileExtension = fileName.substring(dotIndex + 1);
                        }
                        String newFileName = file.getAbsolutePath()
                                .replaceFirst("\\.([a-z]+)", "_" + length + "_" + wide + "." + fileExtension);
                        Thumbnails.of(file)
                                .size(length, wide)
                                .outputFormat(fileExtension)
                                .toFile(newFileName);

                        // 上传到OSS
                        ossClient.putObject(bucketName, "static/" + newFileName, new File(newFileName));

                        // 删除本地临时文件
                        Files.delete(Path.of(newFileName));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).count();

        // 关闭OSS客户端
        ossClient.shutdown();
    }

    /**
     * 文件MD5值获取
     */
    public static String calculateMD5(MultipartFile file) throws IOException, NoSuchAlgorithmException {
        MessageDigest md5Digest = MessageDigest.getInstance("MD5");
        byte[] fileBytes = file.getBytes();
        byte[] digest = md5Digest.digest(fileBytes);
        return DigestUtils.md5DigestAsHex(digest);
    }

    /**
     * 完整上传图片操作
     */
    public static String allUploadImageData(MultipartFile file, ImageMapper imageMapper, String smallPath, List<String> sizeList) {
        String path = null;
        try {
            // 校验 MD5
            String md5 = FileUploadUtil.calculateMD5(file);
            Image image = imageMapper.selectOne(new QueryWrapper<Image>().eq("md5", md5).select("image_id", "origin_path"));
            if (image != null) {
                // 执行更新操作，更新图片表中的 delFlag 字段
                int updateCount = imageMapper.updateDelFlag(md5);
                if (updateCount < 1) {
                    log.error("更新图片 delFlag 失败");
                    throw new BusinessException("更新图片失败");
                }

                // 如果文件小于1MB,则不裁剪
                if (sizeList != null && file.getSize() > 1 * 1024 * 1024) {
                    asyCropping(image.getOriginPath(), sizeList);
                }

                return image.getImageId();
            }

            // 上传图片到 OSS
            path = OssUtil.uploadFile(file, smallPath);

            // 调用图片审核逻辑
            boolean isApproved = false; // 审核方法
            try {
                isApproved = checkImageModeration(path);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!isApproved) {
                OssUtil.deleteFile(path); // 删除不合规图片
                return "图片未通过审核";
            }

            // 记录图片数据
            String imageId = StringUtil.generateShortId();
            //delFlag为0时表示未引用该图片，mq可以删除，大于或等于1时则不能删除
            Image img = new Image(null, imageId, md5, path, null, 0, new Date(), 1);
            int insert = imageMapper.insert(img);
            if (insert < 1) {
                log.error("记录图片数据失败");
                throw new BusinessException("文件上传失败");
            }

            // 压缩图片
            if (sizeList != null && file.getSize() > 1 * 1024 * 1024) {
                asyCropping(path, sizeList);
            }
            return imageId;
        } catch (IOException | NoSuchAlgorithmException e) {
            if (path != null) {
                OssUtil.deleteFile(path);
            }
            throw new BusinessException(e);
        }
    }


    // 图片审核方法
    private static boolean checkImageModeration(String imagePath) throws Exception {
        ImageModerationResponse response = invokeFunction("LTAI5tEoFnVZFfJhw6Wx5VAK", "tJC09gpFLQDYyW3lMCguBGqp4WpZjB", "green-cip.cn-shanghai.aliyuncs.com", imagePath);
        try {
            // 自动路由。
            if (response != null) {
                //区域切换到cn-beijing。
                if (500 == response.getStatusCode() || (response.getBody() != null && 500 == (response.getBody().getCode()))) {
                    // 接入区域和地址请根据实际情况修改。
                    response = invokeFunction("LTAI5tEoFnVZFfJhw6Wx5VAK", "tJC09gpFLQDYyW3lMCguBGqp4WpZjB", "green-cip.cn-beijing.aliyuncs.com", imagePath);
                }
            }
            // 打印检测结果。
            if (response != null) {
                if (response.getStatusCode() == 200) {
                    ImageModerationResponseBody body = response.getBody();
                    System.out.println("requestId=" + body.getRequestId());
                    System.out.println("code=" + body.getCode());
                    System.out.println("msg=" + body.getMsg());
                    if (body.getCode() == 200) {
                        ImageModerationResponseBody.ImageModerationResponseBodyData data = body.getData();

                        System.out.println("dataId=" + data.getDataId());
                        List<ImageModerationResponseBody.ImageModerationResponseBodyDataResult> results = data.getResult();
                        for (ImageModerationResponseBody.ImageModerationResponseBodyDataResult result : results) {
                            double confidence = result.getConfidence();

                            String label = result.getLabel();

                            System.out.println("label=" + label);
                            System.out.println("confidence=" + confidence);

                            System.out.println("description=" + result.getDescription());
                        if(!"nonLabel".equals(label) && confidence > 50){
                            return false;
                        }

                        }
                    } else {
                        System.out.println("image moderation not success. code:" + body.getCode());
                        return false;
                    }
                } else {
                    System.out.println("response not success. status:" + response.getStatusCode());
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//        // 初始化内容安全客户端
//        IClientProfile profile = DefaultProfile.getProfile(
//                "cn-shanghai",  // 地区（根据实际情况调整）
//                "LTAI5tEoFnVZFfJhw6Wx5VAK",  // AccessKey ID
//                "tJC09gpFLQDYyW3lMCguBGqp4WpZjB"  // AccessKey Secret
//        );
//        IAcsClient client = new DefaultAcsClient(profile);
//
//        // 构造图片审核请求
//        ImageSyncScanRequest request = new ImageSyncScanRequest();
//        request.setAcceptFormat(FormatType.JSON);
//        request.setMethod(MethodType.POST);
//        request.setHttpContentType(FormatType.JSON);
//        request.setEncoding("utf-8");
//
//        List<Map<String, Object>> tasks = new ArrayList<>();
//        Map<String, Object> task = new HashMap<>();
//        task.put("dataId", UUID.randomUUID().toString());
//        task.put("url", imagePath); // 图片的 OSS URL
//        task.put("time", new Date());
//        tasks.add(task);
//
//        Map<String, Object> bizData = new HashMap<>();
//        bizData.put("scenes", Arrays.asList("porn", "terrorism", "ad")); // 设置审核场景
//        bizData.put("tasks", tasks);
//        request.setHttpContent(JSON.toJSONString(bizData).getBytes(), "UTF-8", FormatType.JSON);
//
//        HttpResponse httpResponse = null;
//        try {
//            httpResponse = client.doAction(request);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        // 服务端接收到请求，并完成处理后返回的结果。
//        if (httpResponse != null && httpResponse.isSuccess()) {
//            JSONObject scrResponse = JSON.parseObject(org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
//            System.out.println(JSON.toJSONString(scrResponse, true));
//            int requestCode = scrResponse.getIntValue("code");
//            // 每一张图片的检测结果。
//            JSONArray taskResults = scrResponse.getJSONArray("data");
//            if (200 == requestCode) {
//                for (Object taskResult : taskResults) {
//                    // 单张图片的处理结果。
//                    int taskCode = ((JSONObject) taskResult).getIntValue("code");
//                    // 图片对应检测场景的处理结果。如果是多个场景，则会有每个场景的结果。
//                    JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
//                    if (200 == taskCode) {
//                        for (Object sceneResult : sceneResults) {
//                            String scene = ((JSONObject) sceneResult).getString("scene");
//                            String suggestion = ((JSONObject) sceneResult).getString("suggestion");
//                            // 根据scene和suggestion做相关处理。
//                            // 根据不同的suggestion结果做业务上的不同处理。例如，将违规数据删除等。
//                            System.out.println("scene = [" + scene + "]");
//                            System.out.println("suggestion = [" + suggestion + "]");
//                        }
//                    } else {
//                        // 单张图片处理失败，原因视具体的情况详细分析。
//                        System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
//                        return false;
//                    }
//                }
//            } else {
//                /**
//                 * 表明请求整体处理失败，原因视具体的情况详细分析。
//                 */
//                System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
//                return false;
//            }
//        }
//        return true;
        return true;
    }

    /**
     * 创建请求客户端
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @param endpoint
     * @return
     * @throws Exception
     */
    public static Client createClient(String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
        // 接入区域和地址请根据实际情况修改
        // 接入地址列表：https://help.aliyun.com/document_detail/467828.html?#section-uib-qkw-0c8
        config.setEndpoint(endpoint);
        return new Client(config);
    }

    public static ImageModerationResponse invokeFunction(String accessKeyId, String accessKeySecret, String endpoint, String path) throws Exception {
        Client client = createClient(accessKeyId, accessKeySecret, endpoint);

        // 创建运行参数
        RuntimeOptions runtime = new RuntimeOptions();

        // 检测参数构造
        Map<String, Object> serviceParameters = new HashMap<>();
        serviceParameters.put("imageUrl", path);
        serviceParameters.put("dataId", UUID.randomUUID().toString());

        // 配置审核场景
        serviceParameters.put("scenes", Arrays.asList("porn", "terrorism", "ad", "live", "logo", "qrcode", "ocr", "face"));

        ImageModerationRequest request = new ImageModerationRequest();
        request.setService("baselineCheck");
        request.setServiceParameters(JSON.toJSONString(serviceParameters));

        ImageModerationResponse response = null;
        try {
            response = client.imageModerationWithOptions(request, runtime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

}